package com.yuan.java.thread.multhread;

import com.alibaba.fastjson.JSON;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * newCachedThreadPool创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。
 * newFixedThreadPool 创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。
 * newScheduledThreadPool 创建一个定长线程池，支持定时及周期性任务执行。
 * newSingleThreadExecutor 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
 * 判断所有线程执行完毕
 * Created by yuan on 2017/7/25.
 */
public class ThreadTest {

    @Test
    public void exeTest() {
        ExecutorService pool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            pool.execute(new SimpleThread(i));
        }
        pool.shutdown();
        System.out.println("线程提交完毕");
        while (true) {
            if (pool.isTerminated()) {
                System.out.println("所有线程执行完毕");
                break;
            }
        }
    }


    /**
     * 采用 callable 接口 用线程池执行的时候 都在一个线程内 并且一个个顺序执行
     *
     * @throws Exception
     */
    @Test
    public void exeCallable() throws Exception {
        ExecutorService pool = Executors.newCachedThreadPool();
        List<Future<Integer>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Future<Integer> future = pool.submit(new CallableThread(i));
            list.add(future);
        }
        pool.shutdown();
        System.out.println("线程提交完毕");
        List<Integer> integers1 = new ArrayList<>();
        System.out.println(System.currentTimeMillis());
        for (Future<Integer> future : list) {
            //当进行 get的时候就是在等待线程执行结束
            //如果不进行 循环的get 会直接跳到while 循环中
            integers1.add(future.get());
        }
        System.out.println(System.currentTimeMillis());
        while (true) {
            if (pool.isTerminated()) {
                System.out.println("线程执行完毕");
                List<Integer> integers = new ArrayList<>();
                System.out.println(System.currentTimeMillis());
                for (Future<Integer> future : list) {
                    integers.add(future.get());
                }
                System.out.println(System.currentTimeMillis());
                System.out.println(JSON.toJSONString(integers));
                break;
            }
        }
    }

}
